package es.udima.geo.geoserver.rest;

import java.util.Collection;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import es.udima.geo.geoserver.business.GpsDataController;
import es.udima.geo.geoserver.business.UserController;
import es.udima.geo.geoserver.entities.GpsData;
import es.udima.geo.geoserver.entities.GpsDataRetrieveResult;
import es.udima.geo.geoserver.entities.GpsDataRetrieveResultError;
import es.udima.geo.geoserver.entities.UserAction;
import es.udima.geo.geoserver.entities.UserActivityLog;
import es.udima.geo.geoserver.entities.UserSessionError;
import es.udima.geo.geoserver.rest.entities.GpsDataRetrieveRequest;
import es.udima.geo.geoserver.rest.entities.GpsDataRetrieveResponse;
import es.udima.geo.geoserver.rest.entities.GpsDataStoreRequest;
import es.udima.geo.geoserver.rest.entities.GpsDataStoreResponse;
import es.udima.geo.geoserver.rest.entities.IResponseError;

@Path("/gps")
public class GpsDataService {

    public GpsDataService() {
    }

    /**
     * UserId in filter is a mandatory parameter. If no date filter is set it
     * will return the last gps data of the last day the user sent data. If date
     * filter is for more than MAX_DAYS_TO_RETRIVE_GPS_DATA it will return an
     * error.
     * 
     * @param filter
     * @return
     */
    @POST
    @Path("/user")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public GpsDataRetrieveResponse retrieveUserGpsData(GpsDataRetrieveRequest req) {
	UserController uc = new UserController();
	GpsDataRetrieveResponse res = new GpsDataRetrieveResponse();
	
	UserActivityLog activity = new UserActivityLog();
	activity.setUserId(req.getUserSession().getUserId());
	activity.setSessionToken(req.getUserSession().getSessionToken());
	activity.setAction(UserAction.RETRIEVE_GPS_DATA);
	String activityId = uc.startUserActivityLog(activity);
	
	Collection<UserSessionError> sessionErrors = uc.consumeUserSession(req.getUserSession());
	if (!sessionErrors.isEmpty()) {
	    res.addResponseErrors(translateUserSessionErrors(sessionErrors));
	} else {
	    GpsDataController gc = new GpsDataController();
	    GpsDataRetrieveResult gpsRes = gc.retrieveGpsData(req.getFilter());
	    if (gpsRes.isSuccessful()) {
		res.setFilter(gpsRes.getFilter());
		res.setGpsData(gpsRes.getGpsData());
		uc.terminateUserActivityLog(activityId);
	    } else {
		res.addResponseErrors(translateGpsDataRetrieveErrors(gpsRes.getErrors()));
	    }
	}

	return res;
    }
    
    @POST
    @Path("/store")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public GpsDataStoreResponse storeUserGpsData(GpsDataStoreRequest req) {
	UserController uc = new UserController();
	GpsDataStoreResponse res = new GpsDataStoreResponse();
	
	UserActivityLog activity = new UserActivityLog();
	activity.setUserId(req.getUserSession().getUserId());
	activity.setSessionToken(req.getUserSession().getSessionToken());
	activity.setAction(UserAction.STORE_GPS_DATA);
	String activityId = uc.startUserActivityLog(activity);
	
	Collection<UserSessionError> sessionErrors = uc.consumeUserSession(req.getUserSession());
	if (!sessionErrors.isEmpty()) {
	    res.addResponseErrors(translateUserSessionErrors(sessionErrors));
	} else {
	    String uid = req.getUserSession().getUserId();
	    for(GpsData gd : req.getGpsData()) {
		gd.setUserId(uid);
	    }
	    GpsDataController gc = new GpsDataController();
	    gc.storeGpsData(req.getGpsData());
	    uc.terminateUserActivityLog(activityId);
	}

	return res;
    }

    /*-----------------------------------------------------------------------------------------------*/

    /**
     * 
     * @param errors
     * @return
     */
    private Collection<IResponseError> translateUserSessionErrors(Collection<UserSessionError> errors) {
	return new RestServiceErrorHelper().translateUserSessionErrors(errors);
    }

    /**
     * 
     * @param errors
     * @return
     */
    private Collection<IResponseError> translateGpsDataRetrieveErrors(Collection<GpsDataRetrieveResultError> errors) {
	return new RestServiceErrorHelper().translateGpsDataRetrieveErrors(errors);
    }
}
